package com.zenithmind.coding.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.coding.pojo.entity.Submission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 代码提交Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface SubmissionMapper extends BaseMapper<Submission> {

    /**
     * 分页查询提交记录
     * 
     * @param page 分页参数
     * @param userId 用户ID
     * @param problemId 问题ID
     * @param language 编程语言
     * @param status 提交状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 提交记录列表
     */
    IPage<Submission> selectSubmissionPage(Page<Submission> page,
                                          @Param("userId") String userId,
                                          @Param("problemId") String problemId,
                                          @Param("language") String language,
                                          @Param("status") Integer status,
                                          @Param("startTime") LocalDateTime startTime,
                                          @Param("endTime") LocalDateTime endTime);

    /**
     * 查询用户最佳提交
     * 
     * @param userId 用户ID
     * @param problemId 问题ID
     * @return 最佳提交
     */
    Submission selectUserBestSubmission(@Param("userId") String userId,
                                       @Param("problemId") String problemId);

    /**
     * 查询问题的最佳提交
     * 
     * @param problemId 问题ID
     * @param limit 限制数量
     * @return 最佳提交列表
     */
    List<Submission> selectProblemBestSubmissions(@Param("problemId") String problemId,
                                                 @Param("limit") Integer limit);

    /**
     * 查询最近提交
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 最近提交列表
     */
    List<Submission> selectRecentSubmissions(@Param("userId") String userId,
                                           @Param("limit") Integer limit);

    /**
     * 查询公开的优秀提交
     * 
     * @param problemId 问题ID
     * @param language 编程语言
     * @param limit 限制数量
     * @return 优秀提交列表
     */
    List<Submission> selectPublicExcellentSubmissions(@Param("problemId") String problemId,
                                                      @Param("language") String language,
                                                      @Param("limit") Integer limit);

    /**
     * 查询用户提交统计
     * 
     * @param userId 用户ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 提交统计
     */
    UserSubmissionStatistics selectUserSubmissionStatistics(@Param("userId") String userId,
                                                           @Param("startTime") LocalDateTime startTime,
                                                           @Param("endTime") LocalDateTime endTime);

    /**
     * 查询问题提交统计
     * 
     * @param problemId 问题ID
     * @return 问题提交统计
     */
    ProblemSubmissionStatistics selectProblemSubmissionStatistics(@Param("problemId") String problemId);

    /**
     * 查询语言使用统计
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 语言统计列表
     */
    List<LanguageStatistics> selectLanguageStatistics(@Param("startTime") LocalDateTime startTime,
                                                      @Param("endTime") LocalDateTime endTime);

    /**
     * 查询提交趋势
     * 
     * @param days 天数
     * @return 提交趋势列表
     */
    List<SubmissionTrend> selectSubmissionTrend(@Param("days") Integer days);

    /**
     * 查询相似代码
     * 
     * @param problemId 问题ID
     * @param language 编程语言
     * @param codeHash 代码哈希
     * @param threshold 相似度阈值
     * @return 相似提交列表
     */
    List<Submission> selectSimilarSubmissions(@Param("problemId") String problemId,
                                             @Param("language") String language,
                                             @Param("codeHash") String codeHash,
                                             @Param("threshold") Double threshold);

    /**
     * 更新提交状态
     * 
     * @param submissionId 提交ID
     * @param status 状态
     * @param statusMessage 状态消息
     * @param runTime 运行时间
     * @param runMemory 运行内存
     * @param score 得分
     * @return 更新行数
     */
    int updateSubmissionResult(@Param("submissionId") String submissionId,
                              @Param("status") Integer status,
                              @Param("statusMessage") String statusMessage,
                              @Param("runTime") Integer runTime,
                              @Param("runMemory") Integer runMemory,
                              @Param("score") Integer score);

    /**
     * 用户提交统计
     */
    class UserSubmissionStatistics {
        private String userId;
        private Long totalSubmissions;
        private Long acceptedSubmissions;
        private Double acceptRate;
        private Integer avgRunTime;
        private Integer avgMemory;
        private String favoriteLanguage;
        private Integer totalScore;
        private Integer ranking;

        // Getters and Setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        
        public Long getTotalSubmissions() { return totalSubmissions; }
        public void setTotalSubmissions(Long totalSubmissions) { this.totalSubmissions = totalSubmissions; }
        
        public Long getAcceptedSubmissions() { return acceptedSubmissions; }
        public void setAcceptedSubmissions(Long acceptedSubmissions) { this.acceptedSubmissions = acceptedSubmissions; }
        
        public Double getAcceptRate() { return acceptRate; }
        public void setAcceptRate(Double acceptRate) { this.acceptRate = acceptRate; }
        
        public Integer getAvgRunTime() { return avgRunTime; }
        public void setAvgRunTime(Integer avgRunTime) { this.avgRunTime = avgRunTime; }
        
        public Integer getAvgMemory() { return avgMemory; }
        public void setAvgMemory(Integer avgMemory) { this.avgMemory = avgMemory; }
        
        public String getFavoriteLanguage() { return favoriteLanguage; }
        public void setFavoriteLanguage(String favoriteLanguage) { this.favoriteLanguage = favoriteLanguage; }
        
        public Integer getTotalScore() { return totalScore; }
        public void setTotalScore(Integer totalScore) { this.totalScore = totalScore; }
        
        public Integer getRanking() { return ranking; }
        public void setRanking(Integer ranking) { this.ranking = ranking; }
    }

    /**
     * 问题提交统计
     */
    class ProblemSubmissionStatistics {
        private String problemId;
        private Long totalSubmissions;
        private Long acceptedSubmissions;
        private Double acceptRate;
        private Integer avgRunTime;
        private Integer avgMemory;
        private String mostUsedLanguage;
        private Integer bestTime;
        private Integer bestMemory;

        // Getters and Setters
        public String getProblemId() { return problemId; }
        public void setProblemId(String problemId) { this.problemId = problemId; }
        
        public Long getTotalSubmissions() { return totalSubmissions; }
        public void setTotalSubmissions(Long totalSubmissions) { this.totalSubmissions = totalSubmissions; }
        
        public Long getAcceptedSubmissions() { return acceptedSubmissions; }
        public void setAcceptedSubmissions(Long acceptedSubmissions) { this.acceptedSubmissions = acceptedSubmissions; }
        
        public Double getAcceptRate() { return acceptRate; }
        public void setAcceptRate(Double acceptRate) { this.acceptRate = acceptRate; }
        
        public Integer getAvgRunTime() { return avgRunTime; }
        public void setAvgRunTime(Integer avgRunTime) { this.avgRunTime = avgRunTime; }
        
        public Integer getAvgMemory() { return avgMemory; }
        public void setAvgMemory(Integer avgMemory) { this.avgMemory = avgMemory; }
        
        public String getMostUsedLanguage() { return mostUsedLanguage; }
        public void setMostUsedLanguage(String mostUsedLanguage) { this.mostUsedLanguage = mostUsedLanguage; }
        
        public Integer getBestTime() { return bestTime; }
        public void setBestTime(Integer bestTime) { this.bestTime = bestTime; }
        
        public Integer getBestMemory() { return bestMemory; }
        public void setBestMemory(Integer bestMemory) { this.bestMemory = bestMemory; }
    }

    /**
     * 语言统计
     */
    class LanguageStatistics {
        private String language;
        private Long count;
        private Double percentage;
        private Double avgAcceptRate;
        private Integer avgRunTime;
        private Integer avgMemory;

        // Getters and Setters
        public String getLanguage() { return language; }
        public void setLanguage(String language) { this.language = language; }
        
        public Long getCount() { return count; }
        public void setCount(Long count) { this.count = count; }
        
        public Double getPercentage() { return percentage; }
        public void setPercentage(Double percentage) { this.percentage = percentage; }
        
        public Double getAvgAcceptRate() { return avgAcceptRate; }
        public void setAvgAcceptRate(Double avgAcceptRate) { this.avgAcceptRate = avgAcceptRate; }
        
        public Integer getAvgRunTime() { return avgRunTime; }
        public void setAvgRunTime(Integer avgRunTime) { this.avgRunTime = avgRunTime; }
        
        public Integer getAvgMemory() { return avgMemory; }
        public void setAvgMemory(Integer avgMemory) { this.avgMemory = avgMemory; }
    }

    /**
     * 提交趋势
     */
    class SubmissionTrend {
        private String date;
        private Long totalSubmissions;
        private Long acceptedSubmissions;
        private Double acceptRate;
        private Long uniqueUsers;

        // Getters and Setters
        public String getDate() { return date; }
        public void setDate(String date) { this.date = date; }
        
        public Long getTotalSubmissions() { return totalSubmissions; }
        public void setTotalSubmissions(Long totalSubmissions) { this.totalSubmissions = totalSubmissions; }
        
        public Long getAcceptedSubmissions() { return acceptedSubmissions; }
        public void setAcceptedSubmissions(Long acceptedSubmissions) { this.acceptedSubmissions = acceptedSubmissions; }
        
        public Double getAcceptRate() { return acceptRate; }
        public void setAcceptRate(Double acceptRate) { this.acceptRate = acceptRate; }
        
        public Long getUniqueUsers() { return uniqueUsers; }
        public void setUniqueUsers(Long uniqueUsers) { this.uniqueUsers = uniqueUsers; }
    }
}
